package cn.jbolt.wechat.service;

import cn.jbolt.core.base.JBoltMsg;
import cn.jbolt.core.base.config.JBoltConfig;
import cn.jbolt.core.bean.JBoltAppLinkTarget;
import cn.jbolt.core.common.enums.JBoltApplicationType;
import cn.jbolt.core.common.enums.JBoltSystemLogTargetType;
import cn.jbolt.core.db.sql.Sql;
import cn.jbolt.core.kit.JBoltUserKit;
import cn.jbolt.core.model.Application;
import cn.jbolt.core.service.JBoltApplicationService;
import cn.jbolt.core.service.base.JBoltBaseService;
import cn.jbolt.core.util.JBoltRealUrlUtil;
import cn.jbolt.wechat.cache.JBoltWechatMpinfoCache;
import cn.jbolt.wechat.common.WechatMpinfoType;
import cn.jbolt.wechat.model.WechatMpinfo;
import com.jfinal.aop.Inject;
import com.jfinal.kit.Kv;
import com.jfinal.kit.Okv;
import com.jfinal.kit.Ret;
import com.jfinal.plugin.activerecord.Page;

import java.util.Date;
import java.util.List;

/**
 * 微信公众平台管理
 *
 * @ClassName: WechatMpinfoService
 * @author: 山东小木
 * @date: 2023-10-13 16:05
 */
public class JBoltWechatMpinfoService extends JBoltBaseService<WechatMpinfo> {
    private final WechatMpinfo dao = new WechatMpinfo().dao();

    @Inject
    private JBoltApplicationService jBoltApplicationService;
    @Inject
    private JBoltWechatConfigService jBoltWechatConfigService;
    @Inject
    private JBoltWechatMenuService jBoltWechatMenuService;
    @Inject
    private JBoltWechatAutoReplyService jBoltWechatAutoReplyService;
    @Inject
    private JBoltWechatMediaService jBoltWechatMediaService;

    @Override
    protected WechatMpinfo dao() {
        return dao;
    }

    @Override
    protected int systemLogTargetType() {
        return JBoltSystemLogTargetType.WECHAT_MPINFO.getValue();
    }

    /**
     * 后台管理数据查询
     *
     * @param pageNumber      第几页
     * @param pageSize        每页几条数据
     * @param keywords        关键词
     * @param sortColumn      排序列名
     * @param sortType        排序方式 asc desc
     * @param type            类型
     * @param enable          是否启用
     * @param isAuthenticated 是否已认证
     * @param subjectType     申请认证主体的类型 个人还是企业
     * @return
     */
    public Page<WechatMpinfo> getAdminDatas(int pageNumber, int pageSize, String keywords, String sortColumn, String sortType, Integer type, Boolean enable, Boolean isAuthenticated, Integer subjectType) {
        //创建sql对象
        Sql sql = selectSql().page(pageNumber, pageSize);
        //sql条件处理
        sql.eq("type", type);
        sql.eqBooleanToChar("enable", enable);
        sql.eqBooleanToChar("is_authenticated", isAuthenticated);
        sql.eq("subject_type", subjectType);
        //关键词模糊查询
        sql.likeMulti(keywords, "name", "brief_info", "remark");
        //排序
        sql.orderBy(sortColumn, sortType);
        return paginate(sql);
    }

    /**
     * 保存
     *
     * @param wechatMpinfo
     * @return
     */
    public Ret save(WechatMpinfo wechatMpinfo) {
        if (wechatMpinfo == null || isOk(wechatMpinfo.getId())) {
            return fail(JBoltMsg.PARAM_ERROR);
        }
        boolean success = wechatMpinfo.save();
        if (success) {
            //添加日志
            addSaveSystemLog(wechatMpinfo.getId(), JBoltUserKit.getUserId(), wechatMpinfo.getName());
        }
        return ret(success);
    }

    /**
     * 更新
     *
     * @param wechatMpinfo
     * @return
     */
    public Ret update(WechatMpinfo wechatMpinfo) {
        if (wechatMpinfo == null || notOk(wechatMpinfo.getId()) || notOk(wechatMpinfo.getName()) || notOk(wechatMpinfo.getType())) {
            return fail(JBoltMsg.PARAM_ERROR);
        }
        //更新时需要判断数据存在
        WechatMpinfo dbWechatMpinfo = findById(wechatMpinfo.getId());
        if (dbWechatMpinfo == null) {
            return fail(JBoltMsg.DATA_NOT_EXIST);
        }
        //不能轻易修改enable
        wechatMpinfo.remove("enable");
        String name = wechatMpinfo.getName().trim();
        if (existsName(name, wechatMpinfo.getId())) {
            return fail(JBoltMsg.DATA_SAME_NAME_EXIST);
        }
        wechatMpinfo.setName(name);
        wechatMpinfo.setUpdateUserId(JBoltUserKit.getUserId());
        wechatMpinfo.setUpdateTime(new Date());
        boolean success = wechatMpinfo.update();
        if (success) {
            //添加日志
            addUpdateSystemLog(wechatMpinfo.getId(), JBoltUserKit.getUserId(), wechatMpinfo.getName());
        }
        return ret(success);
    }

    /**
     * 检测是否可以删除
     *
     * @param wechatMpinfo 要删除的model
     * @param kv           携带额外参数一般用不上
     * @return
     */
    @Override
    public String checkCanDelete(WechatMpinfo wechatMpinfo, Kv kv) {
        //如果检测被用了 返回信息 则阻止删除 如果返回null 则正常执行删除
        return checkInUse(wechatMpinfo, kv);
    }

    /**
     * 删除数据后执行的回调
     *
     * @param wechatMpinfo 要删除的model
     * @param kv           携带额外参数一般用不上
     * @return
     */
    @Override
    protected String afterDelete(WechatMpinfo wechatMpinfo, Kv kv) {
        addDeleteSystemLog(wechatMpinfo.getId(), JBoltUserKit.getUserId(), wechatMpinfo.getName());
        return null;
    }

    /**
     * 检测是否可以删除
     *
     * @param wechatMpinfo model
     * @param kv           携带额外参数一般用不上
     * @return
     */
    @Override
    public String checkInUse(WechatMpinfo wechatMpinfo, Kv kv) {
        boolean wechatConfig = jBoltWechatConfigService.checkWechatMpinfoInUse(wechatMpinfo.getId());
        if (wechatConfig) {
            return "此公众平台下已经存在相关配置信息";
        }
        boolean wechatMenu = jBoltWechatMenuService.checkWechatMpinfoInUse(wechatMpinfo.getId());
        if (wechatMenu) {
            return "此公众平台下已经存在菜单配置";
        }
        boolean wechatAutoReply = jBoltWechatAutoReplyService.checkWechatMpinfoInUse(wechatMpinfo.getId());
        if (wechatAutoReply) {
            return "此公众平台下已经存在自动回复规则配置";
        }
        return null;
    }

    /**
     * toggle操作执行后的回调处理
     */
    @Override
    protected String afterToggleBoolean(WechatMpinfo wechatMpinfo, String column, Kv kv) {
        addUpdateSystemLog(wechatMpinfo.getId(), JBoltUserKit.getUserId(), wechatMpinfo.getName(), "的字段[" + column + "]值:" + wechatMpinfo.get(column));
        switch (column) {
            case WechatMpinfo.ENABLE: {
                Boolean enable = wechatMpinfo.getEnable();
                if (enable) {
                    Ret cRet = jBoltWechatConfigService.configOne(wechatMpinfo);
                    if (cRet.isFail()) {
                        wechatMpinfo.setEnable(false);
                        wechatMpinfo.update();
                        return cRet.getStr("msg");
                    }
                } else {
                    jBoltWechatConfigService.removeOneEnableApiConfig(wechatMpinfo.getId());
                }
                //切换开启状态
                break;
            }
            case WechatMpinfo.IS_AUTHENTICATED:
                //切换认证状态
                break;
        }
        return null;
    }


    /**
     * 获取所有启用的公众号
     *
     * @return
     */
    public List<WechatMpinfo> getAllEnableList() {
        return getCommonList(Okv.by(WechatMpinfo.ENABLE, TRUE));
    }


    /**
     * 获取APP关联对象信息
     *
     * @param id
     * @return
     */
    public WechatMpinfo getAppLinkTargetInfo(Long id) {
        WechatMpinfo m = findById(id);
        return m;

    }


    /**
     * 确定关联APP 操作
     *
     * @param mpId
     * @param appId
     * @return
     */
    public Ret submitLinkApp(Long mpId, Long appId) {
        if (notOk(mpId) || notOk(appId)) {
            return fail(JBoltMsg.PARAM_ERROR);
        }
        WechatMpinfo wechatMpinfo = findById(mpId);
        if (wechatMpinfo == null) {
            return fail("公众平台" + JBoltMsg.DATA_NOT_EXIST);
        }
        Application application = jBoltApplicationService.findById(appId);
        if (application == null) {
            return fail("关联应用" + JBoltMsg.DATA_NOT_EXIST);
        }
        if (isOk(application.getLinkTargetId()) && application.getLinkTargetId().longValue() != mpId.longValue()) {
            return fail("应用[" + application.getName() + "]已经被其它 " + application.getTypeName() + " 关联");
        }

        if (wechatMpinfo.getType().intValue() == WechatMpinfoType.XCX.getValue()) {
            if (application.getType().intValue() != JBoltApplicationType.WECHAT_XCX.getValue()) {
                return fail("应用[" + application.getName() + "]类型不是微信小程序,请换个微信小程序应用绑定");
            }
        } else if (application.getType().intValue() != JBoltApplicationType.MP_H5.getValue()) {
            return fail("应用[" + application.getName() + "]类型不是微信公众平台H5,请换个微信公众平台H5应用绑定");
        }

        if (isOk(application.getLinkTargetId()) && application.getLinkTargetId().longValue() == mpId.longValue()) {
            return SUCCESS;
        }
        wechatMpinfo.setLinkAppId(appId);
        application.setLinkTargetId(mpId);
        boolean success_wx = wechatMpinfo.update();
        boolean success_app = application.update();
        if (success_wx && success_app) {
            addUpdateSystemLog(mpId, JBoltUserKit.getUserId(), wechatMpinfo.getName(), "的关联应用为:[" + application.getName() + "(" + application.getTypeName() + ")]");
        }
        return ret(success_wx && success_app);
    }


    /**
     * 解除关联的application
     *
     * @param mpId
     * @return
     */
    public Ret removeLinkApp(Long mpId) {
        if (notOk(mpId)) {
            return fail(JBoltMsg.PARAM_ERROR);
        }
        WechatMpinfo wechatMpinfo = findById(mpId);
        if (wechatMpinfo == null) {
            return fail("公众平台" + JBoltMsg.DATA_NOT_EXIST);
        }
        Long linkAppId = wechatMpinfo.getLinkAppId();
        if (notOk(linkAppId)) {
            return fail("公众平台尚未关联任何应用");
        }
        wechatMpinfo.setLinkAppId(null);
        boolean success = wechatMpinfo.update();
        if (success) {
            jBoltApplicationService.removeLinkTarget(linkAppId);
            addUpdateSystemLog(mpId, JBoltUserKit.getUserId(), wechatMpinfo.getName(), " 与关联应用解除绑定");
        }
        return ret(success);
    }

    /**
     * 根据微信公众平台类型 选择应用列表
     *
     * @param linkMpId 关联的mp
     * @param keywords
     * @param pageSize
     * @return
     */
    public Page<Application> getApplicationByWechatMpinfo(Long linkMpId, String keywords, int pageNumber, int pageSize) {
        if (notOk(linkMpId)) {
            return new Page<>();
        }
        WechatMpinfo wechatMpinfo = JBoltWechatMpinfoCache.me.get(linkMpId);
        if (wechatMpinfo == null) {
            return new Page<>();
        }
        int appType = 0;
        if (wechatMpinfo.getType().intValue() == WechatMpinfoType.XCX.getValue()) {
            appType = JBoltApplicationType.WECHAT_XCX.getValue();
        } else {
            appType = JBoltApplicationType.MP_H5.getValue();
        }
        Sql sql = selectSql().from("jb_application").eq("type", appType).page(pageNumber, pageSize)
                .likeMulti(keywords, "name,app_id");
        if (isOk(linkMpId)) {
            sql.select("*,if(link_target_id=" + linkMpId + ",1,0) as link");
            sql.desc("link desc, id");
        } else {
            sql.desc("id");
        }
        Page<Application> pageData = jBoltApplicationService.paginate(sql);

        return pageData;
    }

    /**
     * 清空配置
     *
     * @param mpId
     * @return
     */
    public Ret clearAllConfigs(Long mpId) {
        if (JBoltConfig.DEMO_MODE) {
            return fail(JBoltMsg.DEMO_MODE_CAN_NOT_DELETE);
        }
        //公众平台配置删除
        jBoltWechatConfigService.deleteByMpId(mpId);
        //删除菜单
        jBoltWechatMenuService.deleteByMpId(mpId);
        //删除自动回复设置
        jBoltWechatAutoReplyService.deleteByMpId(mpId);
        //素材库
        jBoltWechatMediaService.deleteByMpId(mpId);
        return SUCCESS;
    }
}
